/*
 * Copyright (c) 2024 iSOFT INFRASTRUCTURE SOFTWARE CO., LTD.
 * easyAda is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */

#include <plat/config.h>
#include <arch/cpsr.h>
#include <arch/esr.h>
#include <arch/exception_decode.h>
#include <arch/regs.h>
#include <arch/scr.h>
#include <stdlib/stdint.h>
#include <tools/macros.h>
#include <core/schedule.h>
#include <core/dprintf.h>

typedef struct pt_regs {
    unsigned long ttbr0;
    unsigned long hcr;
    unsigned long sctlr;
    unsigned long sp;
    unsigned long spsr;
    unsigned long vbar;
    unsigned long daif;
    unsigned long esr;
    unsigned long elr;
    unsigned long regs[31];
} stack_regs;

void default_exception_handler(stack_regs *context)
{
    uint64_t esr_ec;
    uint64_t esr_il;
    uint64_t esr_iss;
    esr_decode_bit(context->esr, &esr_ec, &esr_il, &esr_iss);
    dprintf("  - ESR : %x { EC:%x IL:%x  ISS:%x }\n", context->esr, esr_ec, esr_il, esr_iss);
    dump_decode_esr(context->esr);
    dprintf("  - DAIF: %x\n", context->daif);
    dprintf("  - ELR : %x\n", context->elr);
    dprintf("  - SPSR: %x\n", context->spsr);
    dprintf("  - SP_EL0: %x\n", context->sp);
    dprintf("  - SCTLR: %x \n", context->sctlr);
    dprintf("  - current_task name = %s \n", current()->name);
    dprintf("error instruction : %x", *(unsigned int *)context->elr);

    while (1)
        ;
}

void handle_sync_entry(stack_regs *pt_regs)
{
    dprintf("synchronous happen! \n");
    default_exception_handler(pt_regs);
}
void handle_irq_entry(context_t *ctx)
{
    extern void irq_traps_entry(context_t * context);
    irq_traps_entry(ctx);

    default_exception_handler(NULL);
}
void handle_fiq_entry(stack_regs *pt_regs)
{
    dprintf("FIR/vFIR happen! \n");
    default_exception_handler(pt_regs);
}

void handle_serror_entry(stack_regs *pt_regs)
{
    dprintf("SError/vSError happen! \n");
    default_exception_handler(pt_regs);
}
